home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
BASIC
/
0007.ZIP
/
LORES.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-03-21
|
47KB
|
1,763 lines
1
; LORES.ASM 3/12/84
; INTERFACE ROUTINES TO USE 160X100 MODE OF COLOR GRAPHICS
TITLE LORES 160X100 GRAPHICS PRIMITIVES.
PAGE 62,100
PUBLIC LORES
; PUBLIC FIRST_INIT,CLS,PLOTDOT,GETDOT
; PUBLIC DRAWLINE,BOX,CIRCLE
; PUBLIC RANDOM,RANDOMIZE
; PUBLIC LETTER,LOPRINT,SLOWLETTER
; PUBLIC SIN,COS,LOPAINT
;
; GENERAL FORM OF ALL ROUTINES FROM BASIC:
;
; CALL LORES%(ROUTINE%,PARMS%(0))
;
; WHERE ROUTINE% IS WHAT IS TO BE DONE,
; AND PARMS%(0) IS AN INTEGER ARRAY OF 6 ELEMENTS WITH SPECS FOR ACTION.
;
; UNLESS THE ROUTINE RETURNS A VALUE, ALL ELEMENTS OF PARMS%(X)
; ARE RETURNED UNCHANGED.
;
TRUE EQU -1
FALSE EQU 0
COMPILER EQU FALSE ; SET TO TRUE FOR COMPILER .OBJ FILE
REGISTER EQU 3D4H
CRT EQU 3D5H
MODE EQU 3D8H
COLORPORT EQU 3D9H
STATUS EQU 3DAH
ROM_TABLE_ADDRESS EQU 0FA6EH ; CHARACTER PATTERNS IN ROM
COLOR_CARD_SEGMENT EQU 0B800H ; WHERE THE ACTION IS
MULT EQU 261 ; FOR RANDOM NUMBER GENERATOR
MODULUS EQU 32749
ABS0 SEGMENT AT 0
ORG 1DH*4
PARM_PTR LABEL DWORD ; FOR VIDEO HORIZONTAL SYNC.
; LORES RESPECTS DOS MODE CO80,R
ABS0 ENDS
; EQUATES FOR DRAWLINE
;
; STACK HAS ADDRESS OF START OF PARMS.
; V(0) = X1 = START COL. (0-159)
; V(1) = Y1 = START ROW (0-99)
; V(2) = X2 = END COLUMN
; V(3) = Y2 = END ROW
; V(4) = COLOR = ( 0-15 )
; V(5) = LENGTH= 0 FOR DRAW WHOLE LINE, ELSE SUB-SET
;
ARG1 EQU WORD PTR [BP+4] ; 4 FOR NEAR CALL, 6 FOR FAR
X1 EQU WORD PTR [SI]
Y1 EQU WORD PTR [SI+2]
X2 EQU WORD PTR [SI+4]
Y2 EQU WORD PTR [SI+6]
COLOR EQU BYTE PTR [SI+8]
LEN EQU WORD PTR [SI+10]
; THESE ARE VALUES THAT WILL BE INSERTED IN THE CODE FOR DRAWLINE
INC_X EQU 41H
DEC_X EQU 49H
INC_Y EQU 42H
DEC_Y EQU 4AH
; THESE ARE ADDRESSES WHERE NEW CODE IS OVERLAYED FOR LINE
ADJ_LONG_AXIS EQU BYTE PTR CS:[DI]
ADJ_MASTER EQU WORD PTR CS:[DI+3]
TEST_MASTER EQU WORD PTR CS:[DI+7]
ALT_ADJ_MASTER EQU WORD PTR CS:[DI+13]
ADJ_SHRT_AXIS EQU BYTE PTR CS:[DI+15]
;CGROUP GROUP CSEG
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CSEG
LORES PROC FAR ; ENTRY FOR ALL LOBIO ROUTINES
PUSH BP
MOV BP,SP
MOV AX,COLOR_CARD_SEGMENT
MOV ES,AX ; ALL ROUTINES ASSUME ES: FOR VIDEO WORK
MOV SI,[BP+8] ; ROUTINE NUMBER
MOV AX,[SI]
SUB AH,AH
SHL AX,1
MOV SI,[BP+6] ; ARRAY(0)
MOV BX,AX
CMP BX,OUT_OF_RANGE
JAE LORET
JMP WORD PTR CS:[BX+OFFSET JUMP_TABLE]
LORET:
PUSH DS
POP ES
POP BP
RET 4
JUMP_TABLE LABEL WORD
DW OFFSET FIRST ; 0 - ARRAY VALUES UNUSED, DUMMY ADDRESS NEEDED
DW OFFSET CLS ; 1 - V(0) = COLOR TO CLEAR SCREEN
DW OFFSET PLOT ; 2 - X, Y, COLOR
DW OFFSET GET ; 3 - X, Y, COLOR RETURNED IN V(2)
DW OFFSET LINE ; 4 - X1,Y1,X2,Y2,COLOR,LENGTH(0 FOR WHOLE LINE)
DW OFFSET BOX ; 5 - X1,Y1,X2,Y2,COLOR,LENGTH(SET TO 0 BY LORES)
DW OFFSET CIRCLE_SETUP ; 6 - X,Y,RADIUS,ASPECT NUM,ASPECT DEN,COLOR
DW OFFSET LETTER1 ; 7 - X(0-11),Y(0-19),ASC(LETTER$),COLOR
DW OFFSET LETTER2 ; 8 - X,Y,LETTER,FOREGROUND,BACKGROUND
DW OFFSET PRINT ; 9 - X,Y,VARPTR(MESSAGE$),COLOR
DW OFFSET PRINT2 ; 10 - DOES NOTHING FOR NOW
DW OFFSET SINE ; 11 - X(IN DEGREES),V(1) RETURNS SIN*10000
DW OFFSET COSINE ; 12 - X(IN DEGREES),V(1) RETURNS COS*10000
DW OFFSET RND ; 13 - IF V(0)=0 RANDOMIZE ELSE V(1) RND 1 TO X
DW OFFSET SWITCH ; 14 - TURN OFF LORES, USE MODE AT TIME OF ENTRY
DW OFFSET LOMODE ; 15 - V(0)=IBM VIDEO MODE ELSE -1 FOR LORES.
DW OFFSET LOPAINT ; 16 - X,Y,FILL,BOUNDARY
OUT_OF_RANGE EQU $-JUMP_TABLE
; 0 1 2 3 4 5 6 7 8 9 OUT 3D4H
VIDEO DB 71H,50H,5AH,0AH,7FH,06H,64H,70H,02H,01H ; OUT 3D5H
; THIS IS THE SETUP FOR LORES MODE TO THE 6845 VIDEO CONTROLLER.
SEED DW 41 ; RANDOM NUMBER SEED
BOXED DW 6 DUP (0) ; STORAGE FOR BOX ROUTINE
VIDMODE DB 0 ; SAVE IBM VIDEO MODE ON INITIALIZATION
LOSTAT DB 0 ; IS LORES ACTIVE?
LOCOLOR DB 0 ; INIT=0, CLS SETS TO VALUE-USED BY PRINT FOR SCROLL
FIRST:
CALL FIRST_INIT
JMP LORET
PLOT:
MOV DX,Y1
MOV CX,X1
MOV AX,X2
SUB AH,AH
CALL PLOTDOT
JMP LORET
GET:
MOV DX,Y1
MOV CX,X1
CALL GETDOT
MOV X2,AX
JMP LORET
LINE:
PUSH SI
CALL DRAWLINE
JMP LORET
CIRCLE_SETUP:
MOV AX,X1 ; X
PUSH AX
MOV AX,Y1 ; Y
PUSH AX
MOV AX,X2 ; RADIUS
OR AX,AX
JZ CIR_ABORT1 ; ZERO FOR RADIUS LEADS TO DIVIDE BY ZERO ERROR
PUSH AX
MOV AX,Y2 ; ASPECT NUMERATOR
OR AX,AX
JZ CIR_ABORT2 ; ZERO IN ASPECT RATIO IS BOGUS TOO
PUSH AX
MOV AX,[SI+8] ; ASPECT DENOMINATOR
OR AX,AX
JZ CIR_ABORT3 ; SO ABORT ROUTINE FOR SAFETY.
PUSH AX
MOV AX,LEN ; COLOR
PUSH AX
CALL CIRCLE
JMP LORET
CIR_ABORT3:
POP AX ; SAFE CIRCLE EXIT FOR ERROR CONDITIONS.
CIR_ABORT2:
POP AX
CIR_ABORT1:
POP AX
POP AX
JMP LORET
LETTER1:
MOV AX,Y2 ; COLOR
MOV AH,AL
MOV BX,X2 ; ASCII VALUE OF LETTER
MOV AL,BL
MOV DX,X1 ; ROW (0-11)
MOV DH,DL
MOV BX,Y1 ; COL (0-19)
MOV DL,BL
CALL LETTER ; PRINT LETTER AT POS. IGNOR BACKGROUND
JMP LORET
LETTER2:
MOV AX,Y2 ; COLOR
MOV AH,AL
MOV AL,COLOR
MOV CL,4
SHL AL,CL
OR AH,AL ; BACKGROUND
MOV BX,X2 ; LETTER
MOV AL,BL
MOV DX,X1 ; ROW
MOV DH,DL
MOV BX,Y1 ; COL
MOV DL,BL
CALL SLOWLETTER ; PRINT LETTER IN COLOR,BACKGROUND - FILL ALL DOTS.
JMP LORET
PRINT:
MOV AX,Y2 ; COLOR. IF BIT 7 SET, PRINT AS XOR
MOV AH,AL
MOV DX,X1 ; ROW (0-11)
MOV DH,DL
MOV BX,Y1 ; COL (0-19)
MOV DL,BL
MOV BX,X2 ; VARPTR OF STRING
PUSH SI
IF COMPILER
MOV CX,[BX] ; COMPILER USES TWO BYTES FOR STRING - MAX LEN=32767
INC BX
INC BX
MOV SI,[BX]
ELSE
MOV CL,[BX] ; INTERPRETER USES ONE BYTE.
SUB CH,CH
INC BX
MOV SI,[BX]
ENDIF
CALL LOPRINT ; THIS WILL FIGURE OUT WHICH WAY TO PRINT.
POP SI ; GET BACK V(0)
SUB AX,AX
MOV AL,DH ; X
MOV X1,AX
MOV AL,DL ; Y
MOV Y1,AX
JMP LORET
PRINT2:
JMP LORET
LOPAINT:
MOV CX,X1 ; COL
MOV DX,Y1 ; ROW
MOV BX,X2 ; FILL COLOR
AND BL,7FH ; XOR IN PAINT LEADS TO PROBLEMS
MOV AX,Y2 ; BOUNDARY COLOR
MOV BH,AL ; BH=BOUND,BL=FILL
MOV AL,CL ; MAKE ONE WORD SINCE
MOV AH,DL ; ROW=0-99,COL=0-159. SAVE STACK SPACE.
PUSH AX ; SAVE ON STACK FOR FIRST.
CALL LOPAINTR ; SOLVE RECURSIVELY
JMP LORET ; BACK I HOPE.
SINE:
MOV AX,X1 ; SIN/COS USE DEGREES, NOT RADIANS
; RETURN RESULT IN V(1) AS VALUE*10000
SINE1:
CMP AX,360 ; SCALE TO 0-319 RANGE.
JB SINE2
SUB AX,360
JMP SINE1
SINE2:
CALL SIN
MOV Y1,AX ; RETURN IN V(1)
JMP LORET
COSINE:
MOV AX,X1
COSINE1:
CMP AX,360
JB COSINE2
SUB AX,360
JMP COSINE1
COSINE2:
CALL COS
MOV Y1,AX
JMP LORET
RND:
MOV AX,X1 ; GET NUMBER
OR AX,AX
JZ RND1 ; IF ITS 0 THEN RESEED GENERATOR
CALL RANDOM
MOV Y1,AX ; ELSE RETURN RND FROM 1 TO X IN ARRAY(1)
JMP LORET
RND1:
CALL RANDOMIZE
MOV AX,0FFFFH ; PUT -1 IN ARRAY(0) TO INDICATE DONE
MOV X1,AX
JMP LORET
LOMODE:
CALL LOMO ; CHECK FOR LORES ACTIVE,
JMP LORET ; ELSE RETURN IBM VIDEO MODE.
LORES ENDP
LOMO PROC NEAR
MOV AL,CS:LOSTAT ; LOSTAT SET TO -1 IF LORES ACTIVE
OR AL,AL
JZ LOMO1
MOV AX,-1
MOV X1,AX
RET
LOMO1:
MOV AH,15 ; IF NOT ACTIVE, RETURN ACTUAL VIDEO STATE
INT 10H
MOV CS:VIDMODE,AL
SUB AH,AH
MOV X1,AX
RET
LOMO ENDP
SWITCH PROC NEAR
; TURN OFF LORES MODE, RESTORING ORIGINAL SCREEN MODE. IF ON MONO, DO NOTHING.
SUB AL,AL
MOV CS:LOSTAT,AL ; INDICATE OFF
MOV AL,CS:VIDMODE
CMP AL,7 ; MONO SCREEN?
JZ SWIT1 ; DON'T DO ANYTHING,
SUB AH,AH ; ELSE RESTORE MODE ON INIT.
PUSH BP
PUSH SI
INT 10H
POP SI
POP BP
SWIT1:
JMP LORET
SWITCH ENDP
FIRST_INIT PROC NEAR
; SET UP SCREEN
; NO REGS CHANGED
PUSH SI
PUSH DX
PUSH CX
PUSH BX
PUSH AX
MOV AH,15 ; STORE CURRENT MODE FOR LATER
INT 10H
MOV CS:VIDMODE,AL
MOV DX,MODE
MOV AL,1 ; TURN OFF VIDEO FOR SETUP
OUT DX,AL
PUSH DS ; SAVE TO GET HORIZ. SYNC FROM TABLE
MOV AX,ABS0
MOV DS,AX ; PARM_PTR AT 0:74H
ASSUME DS:ABS0
LDS BX,PARM_PTR
ADD BX,12H ; POINTS TO 80X25 SYNCH
MOV AL,[BX] ; GET VALUE
POP DS ; BACK TO START VALUE.
ASSUME DS:NOTHING
MOV SI,OFFSET CS:VIDEO
MOV CS:[SI+2],AL ; STORE IN OUR TABLE
MOV DX,REGISTER ; 6845 OUT 3D4 THEN OUT 3D5
MOV CX,10 ; SET TEN REGS
FINIT_LOOP:
MOV AL,10
SUB AL,CL
OUT DX,AL
INC DX
MOV AL,CS:[SI]
OUT DX,AL
INC SI
DEC DX
LOOP FINIT_LOOP
MOV CX,1FFFH
MOV DI,0
MOV AX,00DEH ; SET TO BLACK
CLD
REP STOSW
MOV DX,MODE
MOV AL,9
OUT DX,AL ; RE-ENABLE VIDEO, DISABLE BLINK
MOV AL,0FFH
MOV CS:LOSTAT,AL ; INDICATE ON
SUB AL,AL
MOV CS:LOCOLOR,AL ; COLOR 0 (BLACK)
POP AX
POP BX
POP CX
POP DX
POP SI ; RESTORE-RETURN
RET
FIRST_INIT ENDP
CLS PROC NEAR
; CLS TO COLOR IN AL
; AX CHANGED, OTHERS PRESERVED
MOV AX,[SI] ; COLOR
MOV CS:LOCOLOR,AL ; STORE FOR LATER
AND CS:LOCOLOR,7FH ; STRIP OFF XOR BIT
PUSH DI
PUSH DX
PUSH CX ; SAVE REGS
TEST AL,80H ; WANT AN XOR?
JZ CLS10
CALL CLS_XOR
JMP CLS20
CLS10:
PUSH AX ; SAVE COLOR
MOV DX,MODE
MOV AL,1 ; TURN OFF VIDEO FOR SETUP
OUT DX,AL
MOV CX,1FFFH
MOV DI,0
POP AX ; GET COLOR SPEC
AND AL,0FH ; ONLY 0-15
MOV AH,AL ; COPY
SHL AL,1 ; MOV LO 4 BITS TO HIGH
SHL AL,1
SHL AL,1
SHL AL,1
OR AH,AL ; SAME COLOR TO EACH DOT
MOV AL,0DEH ; CHARACTER FOR SETUP
CLD
REP STOSW
MOV DX,MODE
MOV AL,9
OUT DX,AL ; RE-ENABLE VIDEO, DISABLE BLINK
CLS20:
POP CX ; RESTORE REGS
POP DX
POP DI
JMP LORET ; BACK TO CALLER
CLS_XOR:
PUSH DS
PUSH ES
POP DS ; USE DS TO AVOID SEG OVERRIDE.
PUSH BX
AND AL,0FH ; ONLY 0-15
MOV DI,1 ; FIRST ATTRIBUTE POS.
MOV BL,AL ; COPY COLOR TO BL
MOV CL,4
SHL BL,CL ; SHIFT LO4 BITS TO HI
OR BL,AL ; GET BACK ORIG. BL MAKES TWO DOTS.
MOV CX,8000 ; ATTRIBUTES
MOV DX,STATUS
CLXR10:
IN AL,DX ; WAIT FOR HORIZ. RETRACE
TEST AL,1 ; FOR ACTION
JNZ CLXR10
CLI
CLXR20:
IN AL,DX
TEST AL,1
JZ CLXR20
; XOR TO MEMORY TAKES TOO LONG FOR
MOV AH,[DI] ; HORIZ. RETRACE WINDOW.
STI ; INTERRUPTS OK.
XOR AH,BL
CLXR30:
IN AL,DX ; WAIT FOR HORIZ. RETRACE
TEST AL,1 ; FOR ACTION
JNZ CLXR30
CLI
CLXR40: ; THIS TAKES LONGER, BUT MAKES NO SNOW
IN AL,DX
TEST AL,1
JZ CLXR40
MOV [DI],AH ; BACK TO SCREEN
STI
INC DI ; GET TO NEXT
INC DI
LOOP CLXR10 ; DO TILL DONE.
POP BX ; KEEP IT NEAT
POP DS
RET ; BACK TO CALLER
CLS ENDP
PLOTDOT PROC NEAR
; SET A DOT TO COLOR
; DX = ROW ( 0-99 )
; CX = COL ( 0-159 )
; AL = COLOR
; ASSUMES ES POINTS TO VIDEO MEMORY
; ALL REGS PRESERVED.
; PLOTDOT MIMICS INT 10H WRITE DOT, INCLUDING XOR DOT
PUSH DX
PUSH SI ; SAVE REGS
PUSH CX
PUSH BX
PUSH AX
CMP DX,99 ; DON'T DO FOR OUT OF RANGE
JA PDBRIDGE ; NO JUMP TAKES LESS TIME
CMP CX,159
JA PDBRIDGE
PUSH AX ; SAVE COLOR
MOV AX,DX ; COPY ROW TO AX
SHL AX,1 ; *2 ROW*160=
SHL AX,1 ; *4 ROW*128
SHL AX,1 ; *8
SHL AX,1 ; *16
SHL AX,1 ; *32
SHL AX,1 ; *64
SHL AX,1 ; *128
SHL DX,1 ; *2 + ROW*32
SHL DX,1 ; *4
SHL DX,1 ; *8 IN 27 CLOCKS
SHL DX,1 ; *16 INSTEAD OF ~80
SHL DX,1 ; *32
ADD AX,DX ; ROW*128 + ROW*32
MOV SI,AX ; MOVE TO SI
ADD SI,CX ; + COL
OR SI,1 ; ADJUST FOR ATTRIBUTE
POP BX ; GET BACK COLOR
MOV DX,STATUS
PDW1:
IN AL,DX
TEST AL,1
JNZ PDW1 ; WAIT FOR HORIZ. RETRACE
CLI ; NO MORE INTERRUPTS
PDW2:
IN AL,DX ; GET STATUS
TEST AL,1 ; IS IT HIGH
JZ PDW2 ; WAIT TILL IT IS
MOV BH,ES:[SI] ; GET CURRENT BYTE
STI ; INTERRUPTS OK
TEST CX,1 ; CHECK ODD/EVEN
JZ PD1
TEST BL,80H ; CHECK FOR XOR
JZ PDW2A ; NO, JUMP
MOV CH,BH ; SAVE ORIG
XOR BH,BL ; XOR BOTH
AND BH,0FH ; MASK OUT OTHER DOT
AND CH,0F0H ; MASK OUR DOT
OR BH,CH ; COMBINE
JMP SHORT PDW3 ; ONWARD
PDBRIDGE:
JMP PDRET ; HOP SKIP AND A JUMP
PDW2A:
AND BH,0F0H ; ITS ODD - SET FOREGROUND
AND BL,0FH ; FILTER BOGUS COLOR
OR BH,BL ; COMBINE
PDW3:
IN AL,DX ; WAIT FOR HORIZ. RETRACE
TEST AL,1
JNZ PDW3
CLI
PDW4:
IN AL,DX
TEST AL,1
JZ PDW4
MOV ES:[SI],BH ; BACK TO SCREEN
STI
JMP SHORT PDRET
PD1:
TEST BL,80H ; CHECK FOR XOR
JZ PD1A ; NO-GO ON
SHL BL,1 ; SHIFT TO BACKGROUND
SHL BL,1
SHL BL,1
SHL BL,1
MOV CH,BH ; SAVE ORIG
XOR BH,BL ; XOR BOTH
AND BH,0F0H ; MASK OUT OTHER DOT
AND CH,0FH ; MASK OUR DOT
OR BH,CH ; COMBINE
JMP SHORT PDW5 ; ONWARD
PD1A:
AND BH,0FH ; SAVE FOREGROUND
SHL BL,1 ; SHIFT TO BACKGROUND
SHL BL,1
SHL BL,1
SHL BL,1
OR BH,BL ; COMBINE
PDW5:
IN AL,DX ; WAIT RETRACE TO STORE ON SCREEN
TEST AL,1
JNZ PDW5
CLI
PDW6:
IN AL,DX
TEST AL,1
JZ PDW6
MOV ES:[SI],BH
STI
PDRET:
POP AX
POP BX
POP CX
POP SI
POP DX
RET ; BACK TO CALLER
PLOTDOT ENDP
GETDOT PROC NEAR
; GET A DOT, RETURN COLOR
; DX = ROW ( 0-99 )
; CX = COL ( 0-159 )
; RETURNS AX = COLOR, OR -1 IF REQUEST OUT OF RANGE
; ASSUMES ES POINTS TO VIDEO MEMORY
PUSH DX
PUSH SI ; SAVE REGS
PUSH CX
PUSH BX
CMP DX,99 ; DON'T DO FOR OUT OF RANGE
JA GDRET_BAD
CMP CX,159
JA GDRET_BAD
MOV AX,DX
MOV BL,160
MUL BL ; 160 * ROW
MOV SI,AX
ADD SI,CX ; + COL
OR SI,1 ; ADJUST FOR ATTRIBUTE
MOV DX,STATUS
GDW1:
IN AL,DX
TEST AL,1
JNZ GDW1 ; WAIT FOR HORIZ. RETRACE
CLI ; NO MORE INTERRUPTS
GDW2:
IN AL,DX ; GET STATUS
TEST AL,1 ; IS IT HIGH
JZ GDW2 ; WAIT TILL IT IS
MOV AL,ES:[SI] ; GET CURRENT BYTE
STI ; INTERRUPTS OK
TEST CL,1 ; ODD?
JZ GD1
AND AL,0FH ; FILTER OTHER DOT
SUB AH,AH
JMP SHORT GDRET ;BACK
GD1:
MOV CL,4
SHR AL,CL ; HI DOT TO LOW
SUB AH,AH
JMP SHORT GDRET
GDRET_BAD:
MOV AX,0FFFFH ; -1 = OUT OF RANGE
GDRET:
POP BX
POP CX
POP SI
POP DX
RET
GETDOT ENDP
; DRAWLINE.ASM - - AS A NEAR CALL
; FROM DR. DOBBS -- JUNE 1983, P.75
; USES FAST-LINE DRAWING TECHNIQUE FROM BYTE, AUG. 81
;
; ARGS IN ARRAY PARMS
; X1 Y1 X2 Y2 COLOR LEN
; PUSH PARMS OFFSET ON STACK, DISCARDED ON RETURN
; I.E. PUSH ADDRESS_OF_FIRST_ARRAY_ELEMENT
; DON'T EXPECT IT TO BE THERE ON RETURN
; SEGMENTS, BP PRESERVED, OTHERS CHANGED.
DRAWLINE PROC NEAR
PUSH BP
MOV BP,SP
MOV SI,ARG1 ; I.E. V%(0)
MOV BL,INC_X
MOV AX,X2
SUB AX,X1
JGE DL1
MOV BL,DEC_X
NEG AX
DL1:
MOV CX,AX
MOV BH,INC_Y
MOV AX,Y2
SUB AX,Y1
JGE DL2
MOV BH,DEC_Y
NEG AX
DL2:
MOV DX,AX
MOV DI,OFFSET CS:MODIFY_BASE
CMP DX,CX
JGE DL3
XCHG CX,DX
XCHG BL,BH
DL3:
MOV ADJ_LONG_AXIS,BH
MOV ADJ_MASTER,CX
SHR CX,1
MOV TEST_MASTER,CX
MOV ALT_ADJ_MASTER,DX
MOV ADJ_SHRT_AXIS,BL
MOV DI,DX
CMP LEN,0
JLE DL4
MOV DI,LEN
DL4:
MOV CX,X1
MOV DX,Y1
MOV AL,COLOR
SUB BX,BX
DL5:
CALL PLOTDOT
MODIFY_BASE LABEL BYTE
INC CX
ADD BX,1111H
CMP BX,1111H
JLE DL6
SUB BX,1111H
INC DX
DL6:
DEC DI
JGE DL5
POP BP
RET 2
DRAWLINE ENDP
BOX PROC NEAR
; PARMS SET UP IN BOXED
; SEGMENTS, BP PRESERVED, OTHERS CHANGED
MOV DI,OFFSET BOXED
PUSH DI
PUSH SI ; SAVE FOR US
PUSH ES
PUSH CS
POP ES
MOV CX,12 ; GET ARGS TO TEMP AREA
CLD
REP MOVSB
POP ES
POP SI
POP DI
MOV AX,CS:BOXED ; BX1
MOV X1,AX
MOV AX,CS:BOXED+2 ; BY1
MOV Y1,AX
MOV Y2,AX ; Y2=Y1
MOV AX,CS:BOXED+4 ; BX2
MOV X2,AX
SUB AX,AX
MOV LEN,AX ; LENGTH = WHOLE
PUSH SI
PUSH SI ; STORE FOR DRAWLINE
CALL DRAWLINE
POP SI
PUSH SI
MOV AX,CS:BOXED+4 ; BX2
MOV X1,AX
MOV AX,CS:BOXED+6 ; BY2
MOV Y2,AX ; Y2 (Y1 OK FROM LAST)
PUSH SI
CALL DRAWLINE
POP SI
PUSH SI
MOV AX,CS:BOXED+6 ; BY2
MOV Y1,AX ; Y1
MOV AX,CS:BOXED ; BX1
MOV X2,AX ; X2
PUSH SI
CALL DRAWLINE
POP SI
PUSH SI
MOV AX,CS:BOXED ; BX1
MOV X1,AX ; X1
MOV AX,CS:BOXED+2 ; BY1
MOV Y2,AX ; Y2
PUSH SI
CALL DRAWLINE
POP DI
MOV SI,OFFSET BOXED
PUSH CS
PUSH DS
POP ES
POP DS
MOV CX,12 ; PUT ARGS BACK IN ARRAY
CLD
REP MOVSB
MOV AX,ES
MOV DS,AX
JMP LORET
BOX ENDP
;-----------------------------------
; PROCEDURE
; CIRCLE(X,Y,RADIUS,NUMBER,DENOM,COLOR:INTEGER)
;
; DAN LEE JULY 1, 1982
; SOURCEWARE
;
; DRAWS A CIRCLE AT CENTER (X,Y) WITH ASPECT
; RATIO NUMER/DENOM; RADIUS IN COLUMN UNITS
;
; ASSUMES ENTRY VIA INTER-SEGMENT CALL,
; MODIFIED HERE AS INTRA-SEGMENT
; FRAME: VALUE X : BP+16
; VALUE Y : BP+14
; VALUE RADIUS : BP+12
; VALUE NUMER : BP+10
; VALUE DENOM : BP+8
; VALUE COLOR : BP+6
; SEGMENTS, BP PRESERVED, OTHERS CHANGED
;--------------------------------------
CIRCLE PROC NEAR
PUSH BP
PUSH BP ; AS SUBSTITUTE FOR NEAR
MOV BP,SP
MOV AX,[BP+10]
MOV BX,1024
IMUL BX
MOV CX,[BP+8]
IDIV CX
PUSH AX
XCHG AX,CX
MOV CX,[BP+10]
IMUL BX
IDIV CX
MOV [BP+8],AX
POP AX
MOV [BP+10],AX
; START BY INCREMENTING Y BY ONE UNIT AND
; DECREMENTING X BY TAN UNITS*INV ASPECT
; START AT (RADIUS,Y) AND PLOT TO 45 DEGREES
MOV AX,[BP+12]
MOV BX,1024
IMUL BX
SUB DI,DI
CR5:
PUSH AX
PUSH DX
SUB BX,BX
ADD AX,512
ADC DX,BX
MOV BX,1024
IDIV BX
MOV BX,AX
ADD AX,[BP+16]
MOV DX,[BP+14]
SUB DX,DI
MOV CX,AX
MOV AL,[BP+6]
MOV AH,12
CALL PLOTDOT
SUB CX,BX
SUB CX,BX
CALL PLOTDOT
ADD DX,DI
ADD DX,DI
CALL PLOTDOT
ADD CX,BX
ADD CX,BX
CALL PLOTDOT
; CX NOW AT ORIGINAL POINT
XCHG CX,BX
INC DI
MOV AX,DI
MOV BX,[BP+8]
IMUL BX
IDIV CX
SUB DX,DX
MOV SI,AX
IDIV BX
CMP AX,1
POP DX
POP AX
JAE CR7
NEG SI
MOV BX,-1
ADD AX,SI
ADC DX,BX
JMP SHORT CR5
; PLOT 45 TO 90 DEGREES
; NOW DECREASE X BY ONE UNIT AND
; INCREASE Y BY COT UNITS*ASPECT RATIO
CR7:
MOV AX,DI
MOV BX,1024
IMUL BX
MOV DI,CX
DEC DI
CR8:
PUSH AX
PUSH DX
SUB BX,BX
ADD AX,512
ADC DX,BX
MOV BX,1024
IDIV BX
MOV BX,AX
ADD AX,[BP+14]
MOV CX,[BP+16]
ADD CX,DI
MOV DX,AX
MOV AL,[BP+6]
MOV AH,12
CALL PLOTDOT
SUB CX,DI
SUB CX,DI
CALL PLOTDOT
SUB DX,BX
SUB DX,BX
CALL PLOTDOT
ADD CX,DI
ADD CX,DI
CALL PLOTDOT
SUB DX,[BP+14]
NEG DX
XCHG CX,DX
OR DI,DI
JS CR11
DEC DI
MOV AX,DI
MOV BX,[BP+10]
IMUL BX
IDIV CX
MOV SI,AX
POP DX
POP AX
SUB BX,BX
OR SI,SI
JNS CR10
MOV BX,-1
CR10:
ADD AX,SI
ADC DX,BX
JMP SHORT CR8
; EXIT
CR11:
ADD SP,4
POP BP
POP BP
RET 12
CIRCLE ENDP
LOPAINTR PROC NEAR
; USING BOUNDARY FILL RECURSIVE ALGORITHM
; FROM FUNDAMENTALS OF INTERACTIVE COMPUTER GRAPHICS
; BY J.D. FOLEY AND A. VAN DAM
; ADDISON-WESLEY 1982, P. 450
; HAS ONE STACK DATA AS HI=ROW,LO=COL
; BX HAS BEEN SET WITH COLOR AS BH=BOUNDARY,BL=FILL COLOR
PUSH BP
MOV BP,SP
MOV CL,[BP+4] ; LO BYTE=COL
SUB CH,CH ; 0-159
MOV DL,[BP+5] ; HI BYTE=ROW
SUB DH,DH
MOV SI,CX ; SAVE FOR LEFT SCAN
SCAN_WRITE_RIGHT:
MOV AL,BL ; FILL COLOR
CALL PLOTDOT
INC CX
CALL GETDOT
CMP AL,BL ; IS IT FILL COLOR?
JZ LPR10
CMP AL,BH ; IS IT BOUNDARY COLOR?
JZ LPR10
CMP AL,0FFH ; IS IT OUT OF RANGE?
JZ LPR10
JMP SCAN_WRITE_RIGHT ; NO, KEEP GOING
LPR10:
DEC CX
XCHG SI,CX ; SAVE RIGHTMOST FOR LATER
SCAN_WRITE_LEFT:
MOV AL,BL
CALL PLOTDOT
DEC CX
CALL GETDOT
CMP AL,BL ; IS IT FILL COLOR?
JZ LPR20
CMP AL,BH ; IS IT BOUNDARY COLOR?
JZ LPR20
CMP AL,0FFH ; IS IT OUT OF RANGE?
JZ LPR20
JMP SCAN_WRITE_LEFT ; NO, KEEP GOING
LPR20:
INC CX
MOV DI,CX ; SAVE LEFTMOST
DEC DX ; UP ONE LINE
CMP DX,0 ; IS LESS THAN 0?
JL FIND_DOWN_RIGHT
MOV CX,SI ; RECOVER RIGHT
FIND_UP_RIGHT:
CMP CX,DI ; END OF SCAN?
JL FIND_DOWN_RIGHT
CALL GETDOT
CMP AL,BL ; FILL COLOR?
JZ LPR40 ; SCAN FOR START
CMP AL,BH ; BOUNDARY COLOR?
JZ LPR40
LPR25: ; IF NOT FILL/BOUND, STACK IT
MOV AH,DL ; ROW TO HI
MOV AL,CL ; COL TO LO
PUSH AX ; ITS A START, SAVE ON STACK
LPR30: ; SCAN FOR BOUNDARY/FILL
DEC CX
CMP CX,DI ; END OF SCAN?
JL FIND_DOWN_RIGHT
CALL GETDOT
CMP AL,BL ; IS IT FILL?
JZ LPR40
CMP AL,BH ; OR BOUNDARY?
JZ LPR40 ; IF SO, LOOK FOR START
JMP LPR30 ; ELSE CONTINUE
LPR40:
DEC CX
CMP CX,DI
JL FIND_DOWN_RIGHT
CALL GETDOT
CMP AL,BL ; IS IT FILL?
JZ LPR40
CMP AL,BH ; OR BOUNDARY?
JZ LPR40 ; IF SO CONTINUE SCAN
JMP LPR25 ; ITS A START
FIND_DOWN_RIGHT:
MOV CX,SI ; RECOVER RIGHT
INC DX
INC DX ; SCAN ROW BELOW
CMP DX,99
JA DO_WHILE
CMP CX,DI ; END OF SCAN?
JL DO_WHILE
CALL GETDOT
CMP AL,BL ; FILL COLOR?
JZ LPR60 ; SCAN FOR START
CMP AL,BH ; BOUNDARY COLOR?
JZ LPR60
LPR45:
MOV AH,DL ; ROW TO HI
MOV AL,CL ; COL TO LO
PUSH AX ; ITS A START, SAVE ON STACK
LPR50: ; SCAN FOR BOUNDARY/FILL
DEC CX
CMP CX,DI ; END OF SCAN?
JL DO_WHILE
CALL GETDOT
CMP AL,BL ; IS IT FILL?
JZ LPR60
CMP AL,BH ; OR BOUNDARY?
JZ LPR60 ; IF SO, LOOK FOR START
JMP LPR50 ; ELSE CONTINUE
LPR60:
DEC CX
CMP CX,DI
JL DO_WHILE
CALL GETDOT
CMP AL,BL ; IS IT FILL?
JZ LPR60
CMP AL,BH ; OR BOUNDARY?
JZ LPR60 ; IF SO CONTINUE SCAN
JMP LPR45 ; ITS A START
DO_WHILE:
CMP SP,BP ; ANY PUSHED ADDRESSES?
JAE LPRRET ; SP=BP MEANS NO WORK PENDING
; SP>BP MEANS TROUBLE
CALL LOPAINTR ; RESOLVE STACKED RIGHT ADDRESSES
JMP DO_WHILE ; THEN CHECK AGAIN
LPRRET:
POP BP ; RECOVER LAST FRAME
RET 2 ; DISCARD DATA
LOPAINTR ENDP
RANDOM PROC NEAR
; RETURN RANDOM NUMBER FROM 1 TO AX
; AX CHANGED TO RANDOM, OTHER REGS. PRESERVED
PUSH DX
PUSH CX
PUSH BX
PUSH AX ; RND REQUEST
CALL RN1 ; AX HAS SEED
POP CX ; GET BACK REQUEST
MOV DX,0 ; ONLY 16 BIT
IDIV CX ; DIVIDE
XCHG AX,DX ; JUST WANT REMAINDER
INC AX ; 1 TO AX
POP BX
POP CX
POP DX
RET ; BACK TO CALLER
RN1:
MOV AX,CS:SEED ; SEED @
MOV CX,MULT ; MULT
MOV DX,0 ; CLEAR OUT MSW
IMUL CX ; M*
MOV CX,MODULUS ; MODULUS
IDIV CX ; M/MOD
MOV CS:SEED,DX ; SEED !
XCHG AX,DX ; SET UP FOR MOD
RET
RANDOMIZE:
; RESEED RANDOM NUMBER GENERATOR
; NO REGS CHANGED
PUSH AX
PUSH CX
PUSH DX
SUB AH,AH
INT 1AH ; TIME OF DAY
SUB DH,DH ; DX HAS LOW WORD
XCHG AX,DX
MOV CX,100
DIV CL ; ONLY 8 BITS NEEDED
MOV CL,AH ; GET REMAINDER
INC CX
RN2:
PUSH CX
CALL RN1
POP CX
LOOP RN2
POP DX
POP CX
POP AX
RET
RANDOM ENDP
LETTER PROC NEAR
; PRINTS LETTER IN AL WITH COLOR IN AH
; AT LOCATION SPECIED IN DL,DH
; THERE ARE 12 LINES OF 20 CHARACTERS,
; DH = ROW = 0-11, DL = COL = 0-19.
; FIRST CALCULATE SCREEN POSITION FOR TOP LEFT DOT.
; TRANSLATE DX TO SCREEN COORDINATES.
; THIS IS FAST VERSION, ONLY SETS DOTS THAT ARE ON.
; USE SLOWLETTER FOR BACKGROUND OTHER THAN CURRENT.
PUSH DS ; ONLY AX LOST
PUSH SI
PUSH DX
PUSH CX
PUSH BX
PUSH AX ; SAVE LETTER AND COLOR
MOV AL,DH ; ROW
CBW
SHL AX,1
SHL AX,1 ; 8 DOTS VERTICLE AND HORIZONTAL
SHL AX,1 ; TIMES ROWS
MOV DH,AL ; STORE SCREEN POS. IN DH - 8 BITS OK
MOV AL,DL ; COL
CBW
SHL AX,1
SHL AX,1
SHL AX,1 ; FOR COLUMNS
MOV DL,AL ; STORE SCREEN POS. IN DL
MOV AX,0F000H
MOV DS,AX ; ROM TABLE
MOV SI,ROM_TABLE_ADDRESS
POP CX ; GET BACK LETTER AND COLOR
MOV AL,CL ; 8 BYTES PER CHARACTER
CBW
SHL AX,1
SHL AX,1
SHL AX,1 ; TIMES CHARACTER
ADD SI,AX ; OFFSET INTO TABLE
MOV AL,CH ; COLOR
MOV BL,CH ; STORE HERE TOO
MOV CX,8 ; EIGHT SHOWS UP A LOT
LET1:
PUSH DX ; SAVE SCREEN POS.
MOV AH,[SI] ; GET BIT-PATTERN
MOV BH,80H ; MASK
LET2:
TEST AH,BH ; CHECK FOR DOT
JZ LET4 ; IF NO DOT SKIP
LET3:
PUSH DX
PUSH CX
MOV CL,DL ; COL
MOV CH,0
MOV DL,DH ; ROW
MOV DH,0
CALL PLOTDOT
POP CX
POP DX
LET4:
SHR BH,1 ; MASK
JC LET5 ; WHEN BIT DROPS OUT WE'RE DONE
INC DL ; SET TO NEXT DOT TO RIGHT
JMP LET2
LET5:
POP DX ; GET BACK ORIG.
INC DH ; SET TO NEXT ROW.
INC SI ; SET TO NEXT BYTE.
LOOP LET1 ; DO FOR WHOLE MATRIX (8X8)
POP BX ; RESTORE REGS.
POP CX
POP DX
POP SI
POP DS
RET ; BACK TO CALLER
LETTER ENDP
SLOWLETTER PROC NEAR
; PRINTS LETTER IN AL WITH COLOR IN AH
; AT LOCATION SPECIED IN DL,DH
; THERE ARE 12 LINES OF 20 CHARACTERS,
; DH = ROW = 0-11, DL = COL = 0-19.
; FIRST CALCULATE SCREEN POSITION FOR TOP LEFT DOT.
; TRANSLATE DX TO SCREEN COORDINATES.
PUSH DS ; ONLY AX LOST
PUSH SI
PUSH DX
PUSH CX
PUSH BX
PUSH AX ; SAVE LETTER AND COLOR
MOV AL,DH ; ROW
CBW
SHL AX,1
SHL AX,1 ; 8 DOTS VERTICLE AND HORIZONTAL
SHL AX,1 ; TIMES ROWS
MOV DH,AL ; STORE SCREEN POS. IN DH - 8 BITS OK
MOV AL,DL ; COL
CBW
SHL AX,1
SHL AX,1
SHL AX,1 ; FOR COLUMNS
MOV DL,AL ; STORE SCREEN POS. IN DL
MOV AX,0F000H
MOV DS,AX ; ROM TABLE
MOV SI,ROM_TABLE_ADDRESS
POP CX ; GET BACK LETTER AND COLOR
MOV AL,CL ; 8 BYTES PER CHARACTER
CBW
SHL AX,1
SHL AX,1
SHL AX,1 ; TIMES CHARACTER
ADD SI,AX ; OFFSET INTO TABLE
MOV AL,CH ; COLOR
MOV BL,CH ; STORE HERE TOO
MOV CX,8 ; EIGHT SHOWS UP A LOT
SLET1:
PUSH DX ; SAVE SCREEN POS.
MOV AH,[SI] ; GET BIT-PATTERN
MOV BH,80H ; MASK
SLET2:
TEST AH,BH ; CHECK FOR DOT
JNZ SLET3 ; IF DOT SKIP
PUSH DX ; CODE HERE WILL SET BLACK DOTS
PUSH CX ; IN SPACE WHERE THERE SHOULD BE NO DOTS.
CALL BGRND ; GET BACKGROUND COLOR FOR PLOTDOT
MOV CL,DL ; COL
SUB CH,CH
MOV DL,DH ; ROW
SUB DH,DH
CALL PLOTDOT ; SET TO BLACK
POP CX
POP DX
MOV AL,BL ; GET BACK COLOR
JMP SLET4
SLET3:
PUSH DX
PUSH CX
MOV CL,DL ; COL
SUB CH,CH
MOV DL,DH ; ROW
SUB DH,DH
CALL PLOTDOT
POP CX
POP DX
SLET4:
SHR BH,1 ; MASK
JC SLET5 ; WHEN BIT DROPS OUT WE'RE DONE
INC DL ; SET TO NEXT DOT TO RIGHT
JMP SLET2
SLET5:
POP DX ; GET BACK ORIG.
INC DH ; SET TO NEXT ROW.
INC SI ; SET TO NEXT BYTE.
LOOP SLET1 ; DO FOR WHOLE MATRIX (8X8)
POP BX ; RESTORE REGS.
POP CX
POP DX
POP SI
POP DS
RET ; BACK TO CALLER
BGRND:
; MAKE A BACKGROUND OUT OF AL, ACCOUNT FOR XOR
TEST AL,80H
JNZ BGRND1
SHR AL,1
SHR AL,1
SHR AL,1
SHR AL,1 ; MOVE TO FOREGROUND DOT
RET
BGRND1:
SHR AL,1
SHR AL,1
SHR AL,1
SHR AL,1
OR AL,80H
RET
SLOWLETTER ENDP
LOPRINT PROC NEAR
; PRINT A BASIC STRING - CX HAS LENGTH.
; AT DH=ROW, DL=COL, AH=COLOR, DS:SI POINT TO STRING
; RETURNS WITH DH,DL CONTAINING NEXT LOCATE POSITION
; AX, SI, CX, DX CHANGED. OTHERS OK.
CMP DH,11
JA LOPRET ; REJECT OUT OF RANGE
CMP DL,19
JA LOPRET
OR CX,CX ; EOS?
JZ LOPRET
TEST AH,0F0H ; USING BACKGROUNDS?
JNZ LOP3
LOP1:
MOV AL,[SI] ; GET CHAR
CMP AL,13 ; CR?
JZ LOP1C
CMP AL,8 ; BS?
JNZ LOP1B
CALL BACK_SPACE
JMP SHORT LOP2
LOP1B:
PUSH AX ; COLOR SAVE
CALL LETTER
POP AX
INC DL
CMP DL,20 ; TOO FAR OVER?
JNZ LOP2
LOP1C:
INC DH
CMP DH,12 ; TOO FAR DOWN?
JNZ LOP1A ; SCROLL SCREEN
CALL LOSCROLL
MOV DH,11
LOP1A:
MOV DL,0 ; SET TO START OF NEXT LINE
LOP2:
INC SI
LOOP LOP1
LOPRET:
RET
LOP3:
MOV AL,[SI] ; GET CHAR
CMP AL,13 ; CR?
JZ LOP3C
CMP AL,8 ; BS?
JNZ LOP3B
CALL BACK_SPACE
JMP SHORT LOP4
LOP3B:
PUSH AX ; COLOR SAVE
CALL SLOWLETTER
POP AX
INC DL
CMP DL,20 ; TOO FAR OVER?
JNZ LOP4
LOP3C:
INC DH
CMP DH,12 ; TOO FAR DOWN?
JNZ LOP3A ; SCROLL SCREEN
CALL LOSCROLL
MOV DH,11
LOP3A:
MOV DL,0 ; SET TO START OF NEXT LINE
LOP4:
INC SI
LOOP LOP3
JMP LOPRET
LOPRINT ENDP
BACK_SPACE PROC NEAR
PUSH AX
PUSH CX
OR DL,DL ; AT FIRST COL?
JNZ BS1
OR DH,DH ; AT FIRST ROW?
JZ BSRET ; NOTHING TO DO.
DEC DH ; ELSE SET TO ONE ROW UP
MOV DL,20 ; AND LAST COL+1
BS1:
DEC DL ; ONE SPACE BACK
MOV AL,' ' ; MAKE A SPACE
MOV AH,CS:LOCOLOR ; BACKGROUND COLOR
MOV CL,4 ; MOVE TO BKGRND
SHL AH,CL
CALL SLOWLETTER ; MAKE IT
BSRET:
POP CX
TE<P AX
RET
BACK_SPACE ENDP
LOS}ICROLL PROC NEAR
; SCROLL LORES SCREEN 1 ROW, US]IeQ~BW7->K\K\{}i{_S7E VALUE IN LOCOLOR FOR BHLANK ROW
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DS
PUSH ES
POP DS ; ES,DS POINT TO VIDEO
MOV SI,1280 ; ROW 1, COL 0
MOV DI,0 ; ROW 0, COL 0
MOV CX,14720 ; 160 BYTES/ROW * 92 ROWS
MOV DX,MODE
MOV AL,1
OUT DX,AL ; TURN OFF VIDEO OR IT WILL START SNOWING
CLD
REP MOVSB ; DO SCROLL
MOV AH,CS:LOCOLOR ; USE LAST CLS OR INIT FOR BLANK LINE
AND AH,0FH ;
MOV BL,AH
MOV CL,4
SHL BL,CL ; MOVE COLOR INTO BOTH HALVES OF ATTRIBUTE
OR AH,BL ; COMBINE
MOV AL,0DEH ; CHAR 222
MOV DI,14080 ; ROW 88, COL 0
MOV CX,960
CLD
REP STOSW ; STORE AX IN SCREEN[DI]
MOV DX,MODE
MOV AL,9
OUT DX,AL ; TURN ON VIDEO
POP DS ; GET BACK BASIC INFO
POP SI
POP DX
POP CX
POP BX
POP AX
RET
LOSCROLL ENDP
; TRIG LOOKUP FUNCTIONS
; FROM DR. DOBBS - OCT. 82 P.53
; BY RAY DUNCAN FROM PUBLIC DOMAIN FORTH
; PROGRAM BY JOHN JAMES
TRIG_LOOKUP PROC NEAR
TRIG:
MOV BX,AX
CMP BX,90
JLE TRIG1
SUB BX,180
NEG BX
TRIG1:
SAL BX,1
MOV AX,CS:SINTBL[BX]
RET
COS:
ADD AX,90
SIN:
PUSH DX
PUSH BX
CWD
MOV BX,360
IDIV BX
MOV AX,DX
OR AX,AX
JNS SIN2
ADD AX,360
SIN2:
CMP AX,180
JLE SIN3
SUB AX,180
CALL TRIG
NEG AX
JMP SIN4
SIN3:
CALL TRIG
SIN4:
POP BX
POP DX
RET ; TO CALLER
SINTBL DW 0 ; 0 DEGREES
DW 175
DW 349
DW 523
DW 698
DW 872
DW 1045
DW 1219
DW 1392
DW 1564
DW 1736 ; 10
DW 1908
DW 2079
DW 2250
DW 2419
DW 2588
DW 2756
DW 2924
DW 3090
DW 3256
DW 3420 ; 20
DW 3584
DW 3746
DW 3907
DW 4067
DW 4226
DW 4384
DW 4540
DW 4695
DW 4848
DW 5000 ; 30
DW 5150
DW 5299
DW 5446
DW 5592
DW 5736
DW 5878
DW 6018
DW 6157
DW 6293
DW 6428 ; 40
DW 6561
DW 6691
DW 6820
DW 6947
DW 7071
DW 7193
DW 7314
DW 7431
DW 7547
DW 7660 ; 50
DW 7771
DW 7880
DW 7986
DW 8090
DW 8192
DW 8290
DW 8387
DW 8480
DW 8572
DW 8660 ; 60
DW 8746
DW 8829
DW 8910
DW 8988
DW 9063
DW 9135
DW 9205
DW 9272
DW 9336
DW 9397 ; 70
DW 9455
DW 9511
DW 9563
DW 9613
DW 9659
DW 9703
DW 9744
DW 9781
DW 9816
DW 9848 ; 80
DW 9877
DW 9903
DW 9925
DW 9945
DW 9962
DW 9976
DW 9986
DW 9994
DW 9998
DW 10000 ; 90
TRIG_LOOKUP ENDP
LASTWORD DB 0
CSEG ENDS
END
PRESS ENTER TO CONTINUE: 0000 ; 90
TRIG_LOOKUP